<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 -->
<title>0045: Split a Window into Panes | gtkDcoding</title>
<meta name="generator" content="Jekyll v4.3.4" />
<meta property="og:title" content="0045: Split a Window into Panes" />
<meta name="author" content="Ron Tarrant" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="How to use the GTK Paned class to split a window into panes." />
<meta property="og:description" content="How to use the GTK Paned class to split a window into panes." />
<link rel="canonical" href="http://localhost:4000/posts/0045-split-a-window-into-panes.html" />
<meta property="og:url" content="http://localhost:4000/posts/0045-split-a-window-into-panes.html" />
<meta property="og:site_name" content="gtkDcoding" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2019-06-18T00:00:00-04:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="0045: Split a Window into Panes" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Ron Tarrant"},"dateModified":"2019-06-18T00:00:00-04:00","datePublished":"2019-06-18T00:00:00-04:00","description":"How to use the GTK Paned class to split a window into panes.","headline":"0045: Split a Window into Panes","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/posts/0045-split-a-window-into-panes.html"},"url":"http://localhost:4000/posts/0045-split-a-window-into-panes.html"}</script>
<!-- End Jekyll SEO tag -->
<link rel="stylesheet" href="../assets/main.css">
  <link rel="stylesheet" href="../css/style.css" /><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="gtkDcoding" /></head>
<body><header class="site-header" role="banner">

  <div class="wrapper"><a class="site-title" rel="author" href="../">gtkDcoding</a><nav class="site-nav">
        <input type="checkbox" id="nav-trigger" class="nav-trigger" />
        <label for="nav-trigger">
          <span class="menu-icon">
            <svg viewBox="0 0 18 15" width="18px" height="15px">
              <path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
            </svg>
          </span>
        </label>

        <div class="trigger"><a class="page-link" href="../about.html">About</a><a class="page-link" href="../index-reverse.html">Posts in Date Order</a><a class="page-link" href="../topics.html">Blog Posts by Topic</a></div>
      </nav></div>
</header>
<main class="page-content" aria-label="Content">
      <div class="wrapper">
        <article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
	<header class="post-header">
		<link rel="stylesheet" href="../css/font_size.css" />
		<link rel="stylesheet" href="../css/figure.css" />
		<link rel="stylesheet" href="../css/topics/container.css" />  <!-- sub in the tag/topic -->
		<link rel="stylesheet" href="../css/modal.css" />
		<link rel="stylesheet" href="../css/post.css" />
		<link rel="stylesheet" href="../css/mascot_effects.css" />

		
		
		<p class="post-meta">
		<time class="dt-published" datetime="2019-06-18T00:00:00-04:00" itemprop="datePublished">Tuesday, June 18, 2019
		</time>• by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span class="p-author h-card" itemprop="name">Ron Tarrant</span></span></p>
	</header>

	<div class="post-content e-content" itemprop="articleBody">
		<div class="skew-line"></div>
		<h1 id="0045-split-a-window-into-panes">0045: Split a Window into Panes</h1>

<p>There will be times when you’ll need a window separated into two areas with a handle to adjust the division between them. For instance, a file manager has a directory/folder tree on the left and the contents of a selected directory on the right and as I’m sure you’re aware, if you dig deep enough into a directory hierarchy, you have to widen the left-hand area so you can see the full path which is why it’s handy to have that adjustment handle between the two panes.</p>

<p>Today’s code lays the foundation for this type of functionality.</p>

<h2 id="a-pane-in-the-window-two-really">A Pane in the Window… Two, Really</h2>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img0" src="../images/screenshots/014_container/container_01.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal0" class="modal">																	<!-- modal# -->
				<span class="close0">&times;</span>															<!-- close# -->
				<img class="modal-content" id="img00" />															<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal0");														// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img0");															// img#
			var modalImg = document.getElementById("img00");													// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close0")[0];											// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img1" src="../images/screenshots/014_container/container_01_term.png" alt="Current example terminal output" />		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal1" class="modal">																				<!-- modal# -->
				<span class="close1">&times;</span>																		<!-- close# -->
				<img class="modal-content" id="img11" />																		<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal1");																	// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img1");																		// img#
			var modalImg = document.getElementById("img11");																// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close1")[0];														// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																								<!-- ------------- filename (below) --------- -->
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/014_container/container_01_paned.d" target="_blank">here</a>.
	</div>
</div>

<p>A <code class="language-plaintext highlighter-rouge">Paned</code> container can have its child panes side by side or one below the other. And since we may want programmable access to manipulate the child widgets we put in these panes, I’ve created a class derived from <code class="language-plaintext highlighter-rouge">Paned</code> and called it <code class="language-plaintext highlighter-rouge">SideBySide</code>:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="n">SideBySide</span> <span class="p">:</span> <span class="n">Paned</span>
<span class="p">{</span>
	<span class="n">Image</span> <span class="n">child01</span><span class="p">,</span> <span class="n">child02</span><span class="p">;</span>
	
	<span class="k">this</span><span class="p">()</span>
	<span class="p">{</span>
		<span class="k">super</span><span class="p">(</span><span class="n">Orientation</span><span class="p">.</span><span class="n">HORIZONTAL</span><span class="p">);</span>
		
		<span class="k">auto</span> <span class="n">child01</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Image</span><span class="p">(</span><span class="s">"images/e_blues_open.jpg"</span><span class="p">);</span> 
		<span class="n">add1</span><span class="p">(</span><span class="n">child01</span><span class="p">);</span>
		
		<span class="k">auto</span> <span class="n">child02</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Image</span><span class="p">(</span><span class="s">"images/guitar_bridge.jpg"</span><span class="p">);</span>
		<span class="n">add2</span><span class="p">(</span><span class="n">child02</span><span class="p">);</span>
		
		<span class="n">addOnButtonRelease</span><span class="p">(&amp;</span><span class="n">showDividerPosition</span><span class="p">);</span>
		
	<span class="p">}</span> <span class="c1">// this()</span>
	
	
	<span class="k">public</span> <span class="kt">bool</span> <span class="n">showDividerPosition</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">,</span> <span class="n">Widget</span> <span class="n">widget</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">writeln</span><span class="p">(</span><span class="s">"The divider is set to: "</span><span class="p">,</span> <span class="n">getPosition</span><span class="p">());</span>
		
		<span class="k">return</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
		
	<span class="p">}</span> <span class="c1">// showDividerPosition()</span>
	
<span class="p">}</span> <span class="c1">// class SideBySide</span>
</code></pre></div></div>

<p>This is just about as simple as it gets with <code class="language-plaintext highlighter-rouge">Paned</code> containers. We’ve got two child <code class="language-plaintext highlighter-rouge">Image</code> widgets, each tucked into its own pane.</p>

<p>And just to show off one of <code class="language-plaintext highlighter-rouge">Paned</code>’s functions, I’ve connected up a generic <code class="language-plaintext highlighter-rouge">Widget Event</code> signal to spit out the position of the pane divider handle. Hover the mouse over the handle, click-n-drag, and when you release the mouse button, <code class="language-plaintext highlighter-rouge">showDividerPosition()</code> spits out the new position of the handle.</p>

<h3 id="paned-behaviour">Paned Behaviour</h3>

<p>Because there are only two panes in a <code class="language-plaintext highlighter-rouge">Paned</code> container, the functions for assigning child <code class="language-plaintext highlighter-rouge">Widget</code>s are numbered:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">add1(child1)</code>, and</li>
  <li><code class="language-plaintext highlighter-rouge">add2(child2)</code>.</li>
</ul>

<p>Or if you want to populate both in one go, you can do it with a single function:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">add</span><span class="p">(</span><span class="n">child1</span><span class="p">,</span> <span class="n">child2</span><span class="p">);</span>
</code></pre></div></div>

<p>You could also use <code class="language-plaintext highlighter-rouge">pack1()</code> and <code class="language-plaintext highlighter-rouge">pack2()</code> if you prefer, but the behaviour will be different, so let’s look at that.</p>

<h2 id="paned-packing-a-vertical-version">Paned Packing (a Vertical Version)</h2>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img2" src="../images/screenshots/014_container/container_02.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal2" class="modal">																<!-- modal# -->
				<span class="close2">&times;</span>														<!-- close# -->
				<img class="modal-content" id="img22" />														<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal2");													// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img2");														// img#
			var modalImg = document.getElementById("img22");												// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close2")[0];										// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img3" src="../images/screenshots/014_container/container_02_term.png" alt="Current example terminal output" /> 		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal3" class="modal">																			<!-- modal# -->
				<span class="close3">&times;</span>																	<!-- close# -->
				<img class="modal-content" id="img33" />																	<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal3");																// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img3");																	// img#
			var modalImg = document.getElementById("img33");															// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close3")[0];													// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																							<!--------- filename (below) ------------>
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/014_container/container_02_paned_pack.d" target="_blank">here</a>.
	</div>
</div>

<p>Our second example has a new derived class for a <em>vertical</em> <code class="language-plaintext highlighter-rouge">Paned</code> container:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="n">UppyDowny</span> <span class="p">:</span> <span class="n">Paned</span>
<span class="p">{</span>
	<span class="n">Image</span> <span class="n">child01</span><span class="p">,</span> <span class="n">child02</span><span class="p">;</span>
	
	<span class="k">this</span><span class="p">()</span>
	<span class="p">{</span>
		<span class="k">super</span><span class="p">(</span><span class="n">Orientation</span><span class="p">.</span><span class="n">VERTICAL</span><span class="p">);</span>
		
		<span class="k">auto</span> <span class="n">child01</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Image</span><span class="p">(</span><span class="s">"images/e_blues_open.jpg"</span><span class="p">);</span> 
		<span class="n">pack1</span><span class="p">(</span><span class="n">child01</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
		
		<span class="k">auto</span> <span class="n">child02</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Image</span><span class="p">(</span><span class="s">"images/guitar_bridge_alt.jpg"</span><span class="p">);</span>
		<span class="n">pack2</span><span class="p">(</span><span class="n">child02</span><span class="p">,</span> <span class="kc">false</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
		
		<span class="n">addOnButtonRelease</span><span class="p">(&amp;</span><span class="n">showDividerPosition</span><span class="p">);</span>
		
	<span class="p">}</span> <span class="c1">// this()</span>
	
	
	<span class="k">public</span> <span class="kt">bool</span> <span class="n">showDividerPosition</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">,</span> <span class="n">Widget</span> <span class="n">widget</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">writeln</span><span class="p">(</span><span class="s">"The divider is set to: "</span><span class="p">,</span> <span class="n">getPosition</span><span class="p">());</span>
		
		<span class="k">return</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
		
	<span class="p">}</span> <span class="c1">// showDividerPosition()</span>
	
<span class="p">}</span> <span class="c1">// class UppyDowny</span>
</code></pre></div></div>

<p>Here are the differences between this example and the first:</p>

<ul>
  <li>the panes are stacked vertically instead of horizontally,</li>
  <li><code class="language-plaintext highlighter-rouge">pack1()</code> has three arguments instead of one:
    <ul>
      <li>the child <code class="language-plaintext highlighter-rouge">Widget</code>,</li>
      <li>a <code class="language-plaintext highlighter-rouge">bool</code> to determine whether or not the child will expand when the divider handle is moved away from it, and</li>
      <li>another <code class="language-plaintext highlighter-rouge">bool</code> to control whether or not the child <code class="language-plaintext highlighter-rouge">Widget</code> will shrink when the handle is moved toward it.</li>
    </ul>
  </li>
  <li>when you move the divider handle in the first example, each image slides out of the way as the handle is moved toward it, but…</li>
  <li>in the second example, only the guitar bridge image moves.</li>
</ul>

<p>Note also that even though the panes expand or contract as you move the handle, the <code class="language-plaintext highlighter-rouge">Image</code>s aren’t resizing. So, it’s just the panes that change size, not their contents.</p>

<h3 id="how-addx-imitates-packx">How addX() Imitates packX()</h3>

<p>The default behaviour for <code class="language-plaintext highlighter-rouge">add1()</code> or <code class="language-plaintext highlighter-rouge">add2()</code> allows both panes to resize just as can be done with <code class="language-plaintext highlighter-rouge">pack1()</code> and <code class="language-plaintext highlighter-rouge">pack2()</code>. That’s because when using the <code class="language-plaintext highlighter-rouge">addX()</code> functions, they assume behaviours that would be the same as if you’d used <code class="language-plaintext highlighter-rouge">packX()</code> while passing the following arguments:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">pack1(child1, false, true)</code> = <code class="language-plaintext highlighter-rouge">add(child1)</code>, and</li>
  <li><code class="language-plaintext highlighter-rouge">pack2(child2, true, true)</code> = <code class="language-plaintext highlighter-rouge">add(child2)</code>.</li>
</ul>

<p>The corollary is, if you want to mimic the behaviour of <code class="language-plaintext highlighter-rouge">add1()</code> and <code class="language-plaintext highlighter-rouge">add2()</code>, using the above arguments to <code class="language-plaintext highlighter-rouge">pack1()</code> and <code class="language-plaintext highlighter-rouge">pack2()</code> would do the trick.</p>

<p>And that’s pretty much it for now. See you next time.</p>

<div class="blog-nav">
	<div style="float: left;">
		<a href="./0044-custom-dialog-iii.html">Previous: A Fancy Dialog</a>
	</div>
	<div style="float: right;">
		<a href="./0046-the-spinbutton.html">Next: SpinButton</a>
	</div>
</div>

<p>
	<h3></h3>
<div class="inpage-frame">
	<a href="https://github.com/sponsors/rontarrant">
		<BR>
		<BR>
		<B>Is this article useful? Educational? Entertaining, perhaps?</B>
		<BR>
		<figure class="left">
			<img src="../images/favorite_32.png" alt="Sponsorship heart" style="width: 32px; height: 32px;">
		</figure>
		You're free to accept or decline this invitation to become our newest sponsor.
	</a>
</div>
	<h4 class="comment-blurb"><B>Comments? Questions? Observations?</B></h4>
	<p>
		Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.
	</p>
	<script src="https://utteranc.es/client.js"
		repo="rontarrant"
		issue-term="pathname"
		theme="github-light"
		crossorigin="anonymous"
		async>
	</script>
	<ul>
		<li> come on over to the <a href="https://forum.dlang.org/">D Language Forum</a> and look for one of the <i>gtkDcoding</i> announcement posts, </li>
		<li> drop by <a href="https://forum.gtkd.org/">the <i>GtkD Forum</i></a>,</li>
		<li> follow the link below to email me, or</li>
		<li> go to the	<a href="https://www.facebook.com">gtkDcoding Facebook page.</a></li>
	</ul>
</p>
<p> You can also subscribe <a href="/feed.xml">via RSS</a> so you won't miss anything. Thank you very much for dropping by.</p>
<p>&copy; Copyright 2025 Ron Tarrant </p>
</div>

	<a class="u-url" href="./0045-split-a-window-into-panes.html" hidden></a>
</article>

      </div>
    </main><footer class="site-footer h-card">
  <data class="u-url" href="/"></data>

  <div class="wrapper">

    <h2 class="footer-heading">gtkDcoding</h2>

    <div class="footer-col-wrapper">
      <div class="footer-col footer-col-1">
        <ul class="contact-list">
          <li class="p-name">Ron Tarrant</li><li><a class="u-email" href="mailto:gtkDcoding@gmail.com">gtkDcoding@gmail.com</a></li></ul>
      </div>

      <div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/rontarrant"><svg class="svg-icon"><use xlink:href="../assets/minima-social-icons.svg#github"></use></svg> <span class="username">rontarrant</span></a></li></ul>
</div>

      <div class="footer-col footer-col-3">
        <p>Simple examples of how to use GtkD to build GUI applications.</p>
      </div>
    </div>

  </div>

</footer>
</body>

</html>
